#pragma once
/*
    业务功能: 1.rpc服务的提供;  2,服务注册与发现中的服务提供者管理和服务发现者管理
    服务端封装:
        -注册中心服务端 RegistryServer
        -rpc服务端 RpcServer
        -发布订阅服务端
*/
#include "../common/dispatcher.hpp"
#include "../client/rpc_client.hpp"
#include "rpc_registry.hpp"
#include "rpc_router.hpp"
#include "rpc_topic.hpp"

namespace tmh_rpc
{
    namespace server
    {
        // 注册中心服务端:只需要针对服务注册与发现请求进行处理
        class RegistryServer
        {
        public:
            using ptr = std::shared_ptr<RegistryServer>;
            RegistryServer(int port) : _pd_manager(std::make_shared<PDManager>()),
                                       _dispatcher(std::make_shared<Dispatcher>())
            {
                auto service_cb = std::bind(&PDManager::onServiceRequest, _pd_manager.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<ServiceRequest>(MType::REQ_SERVICE, service_cb);

                _server = tmh_rpc::ServerFactory::create(port);
                auto message_cb = std::bind(&tmh_rpc::Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallback(message_cb);
                auto close_cb = std::bind(&RegistryServer::onConnShutdown, this, std::placeholders::_1);
                _server->setCloseCallback(close_cb);
            }
            void start()
            {
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn)
            {
                _pd_manager->onConnShutdown(conn);
            }

        private:
            PDManager::ptr _pd_manager; // 发现者和提供者数据的管理
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        };

        //Rpc调用的服务端封装
        class RpcServer
        {
        public:
            using ptr = std::shared_ptr<RpcServer>;

            // 服务提供者的地址信息                 是否启用注册                  注册中心的地址信息:启用服务注册后,连接注册中心进行服务注册用的
            RpcServer(const Address &access_addr, bool enableRegistry = false, const Address &regitry_server_addr = Address()) : _enableRegistry(enableRegistry), _access_addr(access_addr),
                                                                                                                                 _router(std::make_shared<server::RpcRouter>()), _dispatcher(std::make_shared<Dispatcher>())
            {
                if (enableRegistry) // 如果启用了注册服务, 那就连接注册中心进行服务注册
                {
                    // 实例化服务注册客户端, 连接服务注册中心
                    _reg_client = std::make_shared<client::RegistryClient>(regitry_server_addr.first, regitry_server_addr.second);
                }

                // 设置回调函数
                // 当前成员_server是一个rpcserver, 用于提供rpc服务
                auto rpc_cb = std::bind(&RpcRouter::onRpcRequest, _router.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<RpcRequest>(MType::REQ_RPC, rpc_cb);
                _server = ServerFactory::create(access_addr.second);
                auto message_cb = bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallback(message_cb);
            }

            // 当启用服务注册后的服务注册接口: 通过_reg_client成员接口进行注册
            void registerMethod(const ServiceDescribe::ptr &service)
            {
                // 进行服务注册这个动作
                if (_enableRegistry)
                {
                    _reg_client->registryMethod(service->method(), _access_addr);
                }
                // 内部对注册进来的服务进行管理
                _router->registerMethod(service);
            }
            void start()
            {
                _server->start();
            }

        private:
            // 是否开启了服务注册
            bool _enableRegistry;

            // 外部的访问地址: 哪个地址提供哪个服务
            Address _access_addr;
            // 当启用服务注册后, 用于发送连接注册服务请求
            client::RegistryClient::ptr _reg_client;
            RpcRouter::ptr _router;
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        };

        // 发布订阅功能的封装
        class TopicServer
        {
        public:
            using ptr = std::shared_ptr<TopicServer>;
            TopicServer(int port) : _topic_manager(std::make_shared<TopicManager>()),
                                    _dispatcher(std::make_shared<Dispatcher>())
            {
                auto topic_cb = std::bind(&TopicManager::onTopicRequest, _topic_manager.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<TopicRequest>(MType::REQ_TOPIC, topic_cb);

                _server = tmh_rpc::ServerFactory::create(port);
                auto message_cb = std::bind(&tmh_rpc::Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallback(message_cb);
                auto close_cb = std::bind(&TopicServer::onConnShutdown, this, std::placeholders::_1);
                _server->setCloseCallback(close_cb);
            }
            void start()
            {
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn)
            {
                _topic_manager->onShutdown(conn);
            }

        private:
            TopicManager::ptr _topic_manager; // 发现者和提供者数据的管理
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        };
    }
}